﻿using System;
using System.IO;
using System.Net;
using System.Text;
using Conusic.Properties;

namespace Conusic
{
    /// <summary>
    /// Description of SimpleHttp.
    /// </summary>
    public static class SimpleHttp
    {
        private const string ContentType = "application/x-www-form-urlencoded; charset=UTF-8";

        public delegate void ErrorHandler(Exception exception);

        public static event ErrorHandler OnError;

        /// <summary>
        /// Request vkontakte page and download it.
        /// </summary>
        /// <param name="url">Relative url(e.g. id32323).</param>
        /// <param name="sid"></param>
        /// <returns>String enterpretation of http page. </returns>
        public static string RequestVkontaktePage(string url)
        {
            ////Wait for Vkontakte access tube
            Config.Instance.VkontakteAccessTube.Wait();

            url = url.Replace("http://vk.com/", String.Empty);
            url = url.Replace("http://vkontakte.ru", String.Empty);

            try
            {
                var request =
                    (HttpWebRequest) WebRequest.Create(Settings.Default.VkontakteAddress + url);
                request.Method = "GET";

                // Parametrize proxy configuration
                Config.Instance.SetProxyConfiguration(request);
                Config.Instance.SetVkontakteCookieForWebRequest(request);

                var response = request.GetResponse();
                var stream = new WebResponseCp1251Reader(response);
                string page = stream.ReadToEndAndCloseAll();
                return page;
            }
            catch (WebException e)
            {
                RaiseError(e);
                throw;
            }
        }

        /// <summary>
        /// Request vkontakte page with post params. Cannot use for send files.
        /// </summary>
        /// <param name="url">Relative url(e.g. id32323).</param>
        /// <param name="postdata">Post data to send. </param>
        /// <returns>Page. </returns>
        public static string RequestVkontaktePage(string url, string postdata)
        {
            //// Wait for Vkontakte access tube
            Config.Instance.VkontakteAccessTube.Wait();

            try
            {
                var request =
                    (HttpWebRequest) WebRequest.Create(Settings.Default.VkontakteAddress + url);

                // Parametrize proxy configuration
                Config.Instance.SetProxyConfiguration(request);
                Config.Instance.SetVkontakteCookieForWebRequest(request);

                request.Method = "POST";
                request.ContentType = ContentType;
                byte[] byteArray = Encoding.UTF8.GetBytes(postdata);
                request.ContentLength = byteArray.Length;

                Stream outputStream = request.GetRequestStream();
                outputStream.Write(byteArray, 0, byteArray.Length);
                outputStream.Close();

                var stream = new WebResponseCp1251Reader(request.GetResponse());
                string page = stream.ReadToEndAndCloseAll();
                return page;
            }
            catch (WebException e)
            {
                RaiseError(e);
                throw;
            }
        }


        public static string RequestPage(string url, string postdata)
        {
            //// Wait for Vkontakte access tube
            Config.Instance.OtherSitesPool.WaitOne();
            string page = null;

            try
            {
                var request = (HttpWebRequest) WebRequest.Create(url);

                // Parametrize proxy configuration
                Config.Instance.SetProxyConfiguration(request);

                request.Method = "POST";
                request.ContentType = ContentType;
                byte[] byteArray = Encoding.UTF8.GetBytes(postdata);
                request.ContentLength = byteArray.Length;

                Stream outputStream = request.GetRequestStream();
                outputStream.Write(byteArray, 0, byteArray.Length);
                outputStream.Close();

                var stream = new WebResponseCp1251Reader(request.GetResponse());
                page = stream.ReadToEndAndCloseAll();
            }
            catch (WebException e)
            {
                RaiseError(e);
                throw;
            }
            finally
            {
                Config.Instance.OtherSitesPool.Release();
            }

            return page;
        }

        public static string RequestPage(string url, Encoding encoding = null)
        {
            Config.Instance.OtherSitesPool.WaitOne();
            string page = null;

            try
            {
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }

                var request = (HttpWebRequest) WebRequest.Create(url);
                request.Method = "GET";
                // Parametrize proxy configuration
                Config.Instance.SetProxyConfiguration(request);
                WebResponse response = request.GetResponse();

                Stream stream = response.GetResponseStream();

                if (stream != null)
                {
                    var reader = new StreamReader(stream, encoding);
                    page = reader.ReadToEnd();
                    stream.Close();
                }
                response.Close();
            }
            catch (WebException e)
            {
                RaiseError(e);
                throw;
            }
            finally
            {
                Config.Instance.OtherSitesPool.Release();
            }

            return page;
        }

        /* public static Stream GetStream(string url)
         {
             Config.Instance.OtherSitesPool.WaitOne();
             try
             {
                 return RequestStream(url);
             }
             catch (Exception e)
             {
                 RaiseError(e);
                 throw;
             }
         }*/

        public static void RaiseError(Exception e)
        {
            // Ignore On 404 message
            if (e is WebException)
            {
                var response = (HttpWebResponse) (e as WebException).Response;
                if (response != null && response.StatusCode == HttpStatusCode.NotFound)
                    return;
            }

            if (OnError != null)
                OnError(e);
        }
    }
}